import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from windows_toasts import WindowsToaster, Toast
import json
import os
import sys
import winreg as reg
import logging  # 导入 logging 模块
import subprocess  # 导入 subprocess 模块

# 设置日志配置
logging.basicConfig(
    level=logging.INFO,  # 设置日志级别为 INFO
    format='%(asctime)s - %(levelname)s - %(message)s',  # 日志格式
    handlers=[
        logging.FileHandler("app.log", encoding='utf-8'),  # 将日志写入文件，使用UTF-8编码
        logging.StreamHandler()  # 同时输出到控制台
    ]
)

# 图标路径
icons = {
    'success_icon': "ico\\Check.ico",#正确的
    'false_icon': "ico\\Cross.ico",#错误的图标

}

# 检查网络连接状态
def check_network_status():
    try:
        response = requests.get("https://www.baidu.com", timeout=5)
        if response.status_code == 200:
            logging.info("网络状态: 已连接")  # 记录网络连接状态
            return "connected"
        else:
            logging.warning("网络状态: 未连接")  # 记录网络断开状态
            return "disconnected"
    except requests.RequestException:
        logging.error("网络状态: 因异常断开连接")  # 记录异常
        return "disconnected"

# 显示系统通知
def show_notification(title, message, icon_key):
    # 从 icons 字典中获取对应的图标路径
    icon_path = icons[icon_key]
    logging.info(f"显示通知: {title} - {message}")  # 记录通知信息

    # 使用 windows_toasts 库显示 Windows 系统原生通知
    try:
        # 创建通知器
        toaster = WindowsToaster('校园网登录助手')
        
        # 创建通知对象
        newToast = Toast()
        
        # 设置通知内容
        newToast.text_fields = [title, message]
        
        # 尝试添加图标（如果图标文件存在）
        if os.path.exists(icon_path):
            try:
                from windows_toasts import ToastDisplayImage
                newToast.AddImage(ToastDisplayImage.fromPath(os.path.abspath(icon_path)))
            except Exception as icon_e:
                logging.warning(f"添加图标失败: {icon_e}")
        
        # 显示通知
        toaster.show_toast(newToast)
        
    except Exception as e:
        logging.error(f"显示系统通知失败: {e}")
        # 如果系统通知失败，使用简单的打印作为备选
        print(f"通知: {title} - {message}")

# 登录校园网
def login_to_website(url, username, password):
    # 使用本地WebDriver驱动
    options = Options()
    options.add_argument("--headless")  # 添加无头模式选项
    options.add_argument("--ignore-certificate-errors")  # 忽略 SSL 证书错误
    
    driver = None
    
    # 使用本地驱动
    local_driver_path = os.path.join('drivers', 'msedgedriver.exe')
    if os.path.exists(local_driver_path):
        try:
            logging.info(f"使用本地WebDriver: {local_driver_path}")
            service = Service(executable_path=local_driver_path)
            driver = webdriver.Edge(service=service, options=options)
            logging.info("成功使用本地驱动初始化WebDriver")
        except Exception as local_e:
            logging.error(f"本地WebDriver启动失败: {local_e}")
            logging.error("请手动下载正确版本的WebDriver")
            raise local_e
    else:
        logging.error(f"本地WebDriver未找到: {local_driver_path}")
        logging.error("请下载Edge WebDriver并将msedgedriver.exe放置在'drivers'文件夹中")
        raise Exception("没有可用的WebDriver")

    try:
        logging.info("正在打开登录页面...")  # 记录打开登录页面
        driver.get(url)

        # 等待用户名输入框出现
        time.sleep(2)
        logging.info("等待用户名输入框可见...")  # 记录等待用户名输入框
        username_field = WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located((By.ID, "username"))
        )
        logging.info("正在输入用户名...")  # 记录输入用户名
        username_field.clear()  # 清空输入框以防有默认值
        username_field.send_keys(username)

        # 等待密码输入框出现
        logging.info("等待密码输入框可见...")  # 记录等待密码输入框
        password_field = WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located((By.ID, "password"))
        )
        logging.info("正在输入密码...")  # 记录输入密码
        password_field.clear()  # 清空输入框以防有默认值
        password_field.send_keys(password)

        # 找到登录按钮并点击
        logging.info("正在查找登录按钮...")  # 记录查找登录按钮
        login_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.ID, "login-account"))
        )
        logging.info("正在点击登录按钮...")  # 记录点击登录按钮
        login_button.click()

        # 检查是否有错误消息
        try:
            error_message = WebDriverWait(driver, 5).until(
                EC.presence_of_element_located((By.CLASS_NAME, "error-message"))  # 假设错误消息的class为"error-message"
            )
            if "账号或密码错误" in error_message.text:
                logging.warning("提供的凭据无效。")  # 记录无效凭据
                show_notification("登录失败", "账号或密码错误，请检查您的凭据。", 'false_icon')
                return False
        except Exception as e:
            logging.info("未找到错误消息，继续检查登录状态。")  # 记录未找到错误消息

        # 检查是否成功登录
        logging.info("等待登出元素出现...")  # 记录等待登出元素
        try:
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.ID, "logout"))
            )
            logging.info("登录成功。")  # 记录登录成功
            show_notification("登录成功", "已成功登录校园网。", 'success_icon')
            return True
        except Exception as e:
            logging.error(f"未找到登出元素: {str(e)}")  # 记录未找到登出元素的错误
            show_notification("登录失败", "登录过程中发生错误，请检查您的用户名和密码。", 'false_icon')
            return False

    except Exception as e:
        logging.error(f"发生错误: {str(e)}")  # 记录发生的错误
        show_notification("系统错误", f"登录过程中发生了错误：{str(e)}", 'false_icon')
        return False

    finally:
        driver.quit()

# 读取配置文件
def read_config(config_file="config.json"):
    if not os.path.exists(config_file):
        # 如果配置文件不存在，则创建一个默认配置文件
        default_config = {
            "url": "",
            "username": "",
            "password": ""
        }
        write_config(config_file, default_config)
        return default_config

    with open(config_file, "r") as f:
        config = json.load(f)
    return config

# 写入配置文件
def write_config(config_file="config.json", data={"url": "", "username": "", "password": ""}):
    with open(config_file, "w") as f:
        json.dump(data, f, indent=4)

def update_webdriver_if_needed():
    """检查本地WebDriver是否存在"""
    local_driver_path = os.path.join('drivers', 'msedgedriver.exe')
    if os.path.exists(local_driver_path):
        logging.info(f"发现本地WebDriver: {local_driver_path}")
        return True
    else:
        logging.warning(f"本地WebDriver未找到: {local_driver_path}")
        logging.info("请下载Edge WebDriver并将msedgedriver.exe放置在'drivers'文件夹中")
        return False

def monitor_network_status():
    # 从配置文件中读取配置
    config_data = read_config()
    url = config_data["url"]
    username = config_data["username"]
    password = config_data["password"]

    last_status = None  # 用于跟踪上次的状态，避免重复通知
    webdriver_check_counter = 0  # WebDriver检测计数器

    while True:
        network_status = check_network_status()
        logging.info(f"网络状态: {network_status}")  # 记录网络状态

        if network_status == "disconnected":
            if last_status != "disconnected":  # 如果状态发生了变化
                print("Network is disconnected. Attempting to log in...")
                logging.info("网络已断开，尝试登录...")  # 记录网络断开信息
                show_notification("网络断开", "正在尝试重新登录...", 'false_icon')
                last_status = "disconnected"

            # 尝试登录
            try:
                if login_to_website(url, username, password):
                    # 登录成功，更新状态
                    print("Login successful!")
                    logging.info("登录成功")  # 记录登录成功信息
                    last_status = "connected"
                    show_notification("认证成功", "已经连接到互联网", 'success_icon')
                else:
                    # 登录失败，等待一段时间后重试
                    time.sleep(10)  # 等待10秒
            except Exception as e:
                logging.error(f"登录失败: {e}")
                if "Could not reach host" in str(e) or "ConnectionError" in str(e):
                    logging.warning("由于网络问题WebDriver下载失败，稍后重试。")
                    show_notification("WebDriver下载失败", "网络问题导致WebDriver下载失败，稍后重试", 'false_icon')
                else:
                    show_notification("登录失败", f"登录过程中出现错误：{str(e)}", 'false_icon')
                time.sleep(10)  # 等待10秒后重试

        elif network_status == "connected":
            if last_status != "connected":  # 如果状态发生了变化
                print("Network is connected. No need to log in.")
                show_notification("网络已连接", "当前已连接到互联网，无需登录。", 'success_icon')
                last_status = "connected"  # 更新最后状态
                
            # 每10秒检测一次WebDriver状态（当计数器达到2时，即10秒）
            webdriver_check_counter += 1
            if webdriver_check_counter >= 2:  # 5秒 * 2 = 10秒
                update_webdriver_if_needed()
                webdriver_check_counter = 0  # 重置计数器

        # 每隔一段时间检查一次网络状态
        time.sleep(5)  # 每5秒检查一次

# Conda环境激活功能已移除，现在使用uv虚拟环境

if __name__ == "__main__":
    monitor_network_status()